package org.smart4j.framework.proxy;

import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ：Anitaxiaofeng
 * @description：代理链
 * @create 2017-12-16
 **/
public class ProxyChain {
   //ProxyManager中声明的ProxyChain
    private final Class<?> targetClass;
    private final Object targetObject;
    private final Method targetMethod;
    private final MethodProxy methodProxy;   //cglib提供的方法代理对象
    private final Object[] methodParams;
    //需要执行的proxy，就是有Aspect注解并且实现proxy接口的那些类，这些类中有before或者是after方法，需要在目标方法周围完成
    //这个是框架所以使用者只要实现proxy接口就可以，具体形成proxyList这些执行的步骤是框架要完成的
    private List<Proxy> proxyList = new ArrayList<Proxy>();
    private int proxyIndex = 0;

    public ProxyChain(Class<?> targetClass,Object targetObject,Method targetMethod,MethodProxy methodProxy,Object[] methodParams,List<Proxy> proxyList){
        this.targetClass = targetClass;
        this.targetObject = targetObject;
        this.targetMethod = targetMethod;
        this.methodProxy = methodProxy;
        this.methodParams = methodParams;
        this.proxyList = proxyList;
    }

    public Object[] getMethodParams(){
        return methodParams;
    }

    public Class<?> getTargetClass(){
        return targetClass;
    }

    public Method getTargetMethod(){
        return targetMethod;
    }

    // 通过proxyIndex来充当代理对象的计数器，若尚未达到proxyList的上限，则从proxyList中取出相应的Proxy对象，并调用
    //其doProxy方法，在Proxy接口的实现中会提供相应的横切逻辑，也就是before、after方法，并且调用doProxyChain，接着进行proxyList中下一个
    //proxy的方法，具体见AspectProxy类，直到proxyIndex达到proxyList的上限为止，最后调用methodProxy的invokeSuper方法
    // 这个是cglib提供的方法，执行目标对象的业务逻辑

    public Object doProxyChain()throws Throwable{
        Object methodResult;
        if(proxyIndex<proxyList.size()){
            methodResult = proxyList.get(proxyIndex).doProxy(this);
        }else{
            methodResult = methodProxy.invokeSuper(targetObject,methodParams);
        }
        return methodResult;
    }


}
